﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using ExtAspNet;
using FJASPX.Framwork.Constant;
using FJASPX.Framwork.Helper;
using FJASPX.Framwork.Model;
using FJASPX.Framwork.Service;
using FJASPX.Framwork.UI;
using NHibernate;
using NHibernate.Criterion;

namespace FJASPX.Framwork.UI
{
    /// <summary>
    /// 管理页面基类
    /// </summary> 
    public abstract class GridPageBase<T> : PageBase where T : Entity
    {
        #region Properties属性

        protected IRepository<T> iRepository;

        /// <summary>
        /// 表格控件
        /// </summary>
        protected Grid gr_Base;

        /// <summary>
        /// 编辑窗口
        /// </summary>
        protected Window win_BEdit;

        /// <summary>
        /// 检索窗口
        /// </summary>
        protected Window win_BSearch;

        /// <summary>
        /// 添加按钮
        /// </summary>
        protected Button btn_BAdd;

        /// <summary>
        /// 删除按钮
        /// </summary>
        protected Button btn_BDelete;
        /// <summary>
        /// 检索按钮
        /// </summary>
        protected Button btn_BSearch;

        /// <summary>
        /// 页数下拉框
        /// </summary>
        protected DropDownList ddl_BPageSize;

        /// <summary>
        /// 查询类型下拉框
        /// </summary>
        protected DropDownList ddl_BSearch;

        /// <summary>
        /// 查询控件
        /// </summary>
        protected TwinTriggerBox ttb_BSearch;

        /// <summary>
        /// 查询控件
        /// </summary>
        protected Timer tir_BMain;

        /// <summary>
        /// 允许添加
        /// </summary>
        protected bool EnableAdd
        {
            get
            {
                return Convert.ToBoolean(this.ViewState[Strings.ADD]);
            }
            set
            {
                this.ViewState[Strings.ADD] = value;
            }
        }

        /// <summary>
        /// 允许编辑
        /// </summary>
        protected bool EnableEdit
        {
            get
            {
                return Convert.ToBoolean(this.ViewState[Strings.EDIT]);
            }
            set
            {
                this.ViewState[Strings.EDIT] = value;
            }
        }

        /// <summary>
        /// 允许删除
        /// </summary>
        protected bool EnableDelete
        {
            get
            {
                return Convert.ToBoolean(this.ViewState[Strings.DELETE]);
            }
            set
            {
                this.ViewState[Strings.DELETE] = value;
            }
        }
        /// <summary>
        /// 允许检索
        /// </summary>
        protected bool EnableSeach
        {
            get
            {
                return Convert.ToBoolean(this.ViewState[Strings.SEARCH]);
            }
            set
            {
                this.ViewState[Strings.SEARCH] = value;
            }
        }
        #endregion

        #region Methods方法

        protected override bool FirstCallRead()
        {
            this.btn_BDelete.Hidden = !EnableDelete;
            this.btn_BAdd.Click += btn_BAdd_Click;
            this.btn_BAdd.Hidden = !EnableAdd;
            this.btn_BSearch.Hidden = !EnableSeach;
            this.ViewState[Strings.SORT_EXPRESSION] = Column.TimeStamp;
            this.ViewState[Strings.SORT_DIRECTION] = Strings.DESC;
            this.InitGrid();
            return true;
        }

        protected void btn_BAdd_Click(object sender, EventArgs e)
        {
            PageContext.RegisterStartupScript(win_BEdit.GetShowReference(Strings.LBF_ADD_URL, Strings.ADD_TITLE));
        }

        /// <summary>
        /// 绑定表格前
        /// </summary>
        protected virtual void BeforeInitGrid()
        {

        }

        /// <summary>
        /// 重新绑定表格
        /// </summary>
        protected virtual void InitGrid()
        {
            BeforeInitGrid();

            List<ICriterion> criterions = new List<ICriterion>();//条件
            List<Order> orders = new List<Order>();//排序 
            criterions.Add(Expression.Like(Strings.USER_NAME, this.CurrentUser.UserName));

            if (ttb_BSearch.ShowTrigger1)
            {
                criterions.Add(Expression.Like(this.ddl_BSearch.SelectedValue, String.Format(Strings.SQL_LIKE, this.ttb_BSearch.Text)));
            }
            else
            {
                this.Search();
            }
            if (this.ViewState[Strings.SORT_EXPRESSION] != null)
            {
                string sortExpression = this.ViewState[Strings.SORT_EXPRESSION].ToString();
                string sortDirection = this.ViewState[Strings.SORT_DIRECTION].ToString();
                orders.Add(new Order(sortExpression, sortDirection.Equals(Strings.ASC)));
            }

            this.PageSize = this.gr_Base.PageSize;
            this.PageIndex = this.gr_Base.PageIndex;

            if (iRepository == null) return;

            this.gr_Base.DataSource = iRepository.PagedQuery(criterions, orders, this.PageIndex, this.PageSize, out this._totalCount);
            this.gr_Base.DataBind();
            this.gr_Base.RecordCount = (int)this.TotalCount;
        }

        /// <summary>
        /// 行事件
        /// </summary>
        /// <param name="commandName">事件名</param>
        /// <param name="keys">关联行键</param>
        protected virtual void RowCommand(string commandName, object[] keys)
        {

        }

        /// <summary>
        /// 导出EXCLE表格
        /// </summary>
        /// <param name="grid"></param>
        protected void ExportGrid(Grid grid)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Strings.TABLE_TOP);
            foreach (GridColumn column in grid.Columns)
            {
                sb.AppendFormat(Strings.TABLE_TD, column.HeaderText);
            }
            sb.Append(Strings.TABLE_TR_END);
            foreach (GridRow row in grid.Rows)
            {
                sb.Append(Strings.TABLE_TR_TOP);
                foreach (object value in row.Values)
                {
                    string html = value.ToString();
                    // 处理CheckBox            
                    if (html.Contains(Strings.CHECKBOK_CHECK))
                    {
                        if (html.Contains(Strings.CHECKBOK_UNCHECK))
                        {
                            html = Strings.ERROR;
                        }
                        else
                        {
                            html = Strings.RIGHT;
                        }
                    }
                    sb.AppendFormat(Strings.TABLE_TD, html);
                } sb.Append(Strings.TABLE_TR_END);
            }
            sb.Append(Strings.TABLE_END);
            Response.ClearContent();
            Response.AddHeader(Strings.CONTENT_DIS, string.Format(Strings.EXCLE_NAME, DateHelper.DATE_TIME));
            Response.ContentType = Strings.EXCLE_MINI;
            Response.Write(sb.ToString());
            Response.End();
        }

        /// <summary>
        /// 检索
        /// </summary>
        protected virtual void Search()
        {

        }

        /// <summary>
        /// 自动刷新
        /// </summary>
        protected virtual void AutoReload()
        {
            if (this.gr_Base.SelectedRowIndexArray.Length.Equals(0))
            {
                this.InitGrid();
            }
        }

        /// <summary>
        /// 删除前，主要用于删除多余文件
        /// </summary>
        protected virtual void BeforeDelete(object id)
        {

        }

        /// <summary>
        /// 删除前，主要用于删除多余文件
        /// </summary>
        protected virtual void BeforeDeletes(object[] ids)
        {

        }

        /// <summary>
        /// 数据库改变后，用于刷新缓存
        /// </summary>
        protected virtual void AfterChange()
        {

        }

        #endregion

        #region Events事件

        /// <summary>
        /// 编辑窗口关闭
        /// </summary>
        protected void win_Edit_Close(object sender, WindowCloseEventArgs e)
        {
            this.gr_Base.PageIndex = 0;
            this.AfterChange();
            this.InitGrid();
            this.tir_BMain.Enabled = true;
        }

        /// <summary>
        /// 检索窗口关闭
        /// </summary>
        protected void win_Search_Close(object sender, WindowCloseEventArgs e)
        {
            this.tir_BMain.Enabled = true;
        }

        /// <summary>
        /// 检索返回
        /// </summary>
        protected void btn_Return_Click(object sender, EventArgs e)
        {
            this.win_BSearch.Hidden = true;
        }

        /// <summary>
        /// 渲染每一行前调用，因此改变了列的属性，那么渲染每一行时此列的属性都发生了变化
        /// </summary>
        protected virtual void Gr_PreRowDataBound(object sender, GridPreRowEventArgs e)
        {
            LinkButtonField lbfEdit = gr_Base.FindColumn(Strings.LBF_EDIT) as LinkButtonField;
            LinkButtonField lbfDelete = gr_Base.FindColumn(Strings.LBF_DELETE) as LinkButtonField;

            if (!this.EnableEdit && lbfEdit != null)
            {
                lbfEdit.Enabled = false;
            }

            if (!this.EnableDelete && lbfDelete != null)
            {
                lbfDelete.Enabled = false;
            }
        }

        /// <summary>
        /// 这个事件会在渲染每一行后调用，此时 Values 属性保存了每一项渲染后的 HTML 片段
        /// </summary>
        protected virtual void Gr_RowDataBound(object sender, GridRowEventArgs e)
        {
            //// e.DataItem  -> System.Data.DataRowView 或者自定义类
            //// e.RowIndex -> 当前行序号（从 0 开始）
            //// e.Values -> 当前行每一列渲染后的 HTML 片段

            ////object a = Grid1.DataKeys[e.RowIndex][0];

            //DataRowView row = e.DataItem as DataRowView;
            //if (row != null)
            //{
            //    e.Values[4] = String.Format("{0} - RowDataBound", e.Values[4]);
            //}
        }

        /// <summary>
        /// 行按钮事件
        /// </summary>
        protected virtual void Gr_RowCommand(object sender, ExtAspNet.GridCommandEventArgs e)
        {
            object[] keys = this.gr_Base.DataKeys[e.RowIndex];
            switch (e.CommandName)
            {
                case Strings.EDIT:
                    if (this.EnableEdit)
                    {
                        PageContext.RegisterStartupScript(win_BEdit.GetShowReference(Strings.LBF_EDIT_URL + keys[0].ToString(), Strings.EDIT_TITLE));
                        this.tir_BMain.Enabled = false;
                    }
                    break;
                case Strings.DELETE:
                    if (this.EnableDelete)
                    {
                        int id = Convert.ToInt32(keys[0]);
                        this.BeforeDelete(id);
                        try
                        {
                            iRepository.DeleteById(id);
                        }
                        catch (Exception ex)
                        {
                            Alert.Show(Message.DELETE_FAIL);
                            Log.WriteLog(Message.ERR, ex);
                            return;
                        }
                        this.AfterChange();
                        this.gr_Base.SelectedRowIndexArray = new int[0];
                        this.InitGrid();
                    }
                    break;
                default:
                    this.RowCommand(e.CommandName, keys);
                    break;
            }
        }

        /// <summary>
        /// 行双击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void Gr_RowDoubleClick(object sender, ExtAspNet.GridRowClickEventArgs e)
        {
            if (this.EnableEdit)
            {
                object[] keys = this.gr_Base.DataKeys[e.RowIndex];
                PageContext.RegisterStartupScript(win_BEdit.GetShowReference(Strings.LBF_EDIT_URL + keys[0].ToString(), Strings.EDIT_TITLE));
                this.tir_BMain.Enabled = false;
            }
        }

        /// <summary>
        /// 排序
        /// </summary>
        protected void Gr_Sort(object sender, ExtAspNet.GridSortEventArgs e)
        {
            this.ViewState[Strings.SORT_EXPRESSION] = e.SortField;
            this.ViewState[Strings.SORT_DIRECTION] = e.SortDirection;
            this.InitGrid();
        }

        /// <summary>
        /// 换页
        /// </summary>
        protected void Gr_PageIndexChange(object sender, GridPageEventArgs e)
        {
            this.gr_Base.PageIndex = e.NewPageIndex;
            this.InitGrid();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        protected void btn_Delete_Click(object sender, EventArgs e)
        {
            if (this.gr_Base.SelectedRowIndexArray.Length == 0)
            {
                Alert.ShowInTop(Message.SELECT_NO_ROW);
                return;
            }
            object[] ids = new object[this.gr_Base.SelectedRowIndexArray.Length];
            for (int i = 0; i < this.gr_Base.SelectedRowIndexArray.Length; i++)
            {
                ids[i] = this.gr_Base.DataKeys[this.gr_Base.SelectedRowIndexArray[i]][0].ToInt();
            }
            this.BeforeDeletes(ids);
            try
            {
                iRepository.DeleteByIds(ids);
            }
            catch (Exception ex)
            {
                Log.WriteLog(Strings.ERROR, ex);
            }
            this.gr_Base.SelectedRowIndexArray = new int[0];
            this.AfterChange();
            this.InitGrid();
        }


        protected void btn_Search_Click(object sender, EventArgs e)
        {
            PageContext.RegisterStartupScript(win_BSearch.GetShowReference());
            this.tir_BMain.Enabled = false;
        }

        /// <summary>
        /// 取消查询
        /// </summary>
        protected void ttb_Search_Trigger1Click(object sender, EventArgs e)
        {
            this.gr_Base.PageIndex = 0;
            this.ttb_BSearch.Text = String.Empty;
            this.ttb_BSearch.ShowTrigger1 = false;
            this.InitGrid();
        }

        /// <summary>
        /// 查询
        /// </summary>
        protected void ttb_Search_Trigger2Click(object sender, EventArgs e)
        {
            this.gr_Base.PageIndex = 0;
            this.ttb_BSearch.ShowTrigger1 = true;
            this.InitGrid();
        }

        /// <summary>
        /// 筛选
        /// </summary>
        protected void btn_XSearch_Click(object sender, EventArgs e)
        {
            this.gr_Base.PageIndex = 0;
            this.ttb_BSearch.Text = String.Empty;
            this.ttb_BSearch.ShowTrigger1 = false;
            this.win_BSearch.Hidden = true;
            this.InitGrid();
        }

        /// <summary>
        /// 导出EXCLE表格
        /// </summary>
        protected void btn_Export_Click(object sender, EventArgs e)
        {
            this.ExportGrid(this.gr_Base);
        }

        /// <summary>
        /// 修改每页记录数
        /// </summary>
        protected void ddl_PageSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.gr_Base.PageIndex = 0;
            this.gr_Base.PageSize = Convert.ToInt32(this.ddl_BPageSize.SelectedValue);
            this.InitGrid();
        }

        /// <summary>
        /// 修改查询列
        /// </summary>
        protected void ddl_Search_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.ttb_BSearch.ShowTrigger1)
            {
                this.gr_Base.PageIndex = 0;
                this.InitGrid();
            }
        }

        /// <summary>
        /// 自动刷新
        /// </summary>
        protected void tir_Main_Tick(object sender, EventArgs e)
        {
            this.AutoReload();
        }

        #endregion
    }
}
